using Nop.Services.Localization;
using Nop.Services.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Nop.Core.Domain.Media;
using Nop.Web.Models.Media;
using StackExchange.Profiling;
using Nop.Core.Caching;
using Nop.Web.Infrastructure.Cache;
using Nop.Core;

namespace Nop.Web.Controllers
{
    public class PictureDisplayController : BaseNopController
    {
        // Fields
        private readonly IPictureDisplayService _pictureDisplayService;
        private readonly IPictureService _pictureService;
        private readonly SlideshowGlobalSettings _slideshowGlobalSettings;
        private readonly ICacheManager _cacheManager;
        private readonly IWorkContext _workContext;
        private readonly IWebHelper _webHelper;

        public PictureDisplayController(
            IPictureDisplayService sliderService, 
            IPictureService pictureService,
            SlideshowGlobalSettings slideshowGlobalSettings,
            ICacheManager cacheManager,
            IWorkContext workContext,
            IWebHelper webHelper
            )
        {
            this._pictureDisplayService = sliderService;
            this._pictureService = pictureService;
            this._slideshowGlobalSettings = slideshowGlobalSettings;
            this._cacheManager = cacheManager;
            this._workContext = workContext;
            this._webHelper = webHelper;
        }

        [ChildActionOnly]
        public ActionResult StaticLinkShow(int type, string contentCategory = null, int contentId = 0)
        {
            PictureDisplayType t = (PictureDisplayType)type;
            t |= PictureDisplayType.StaticLink;

            IList<Slideshow> ss = _pictureDisplayService.GetSlideshowsByTypeAndContentCategory(t, contentCategory, contentId, true);

            var ts = from s in ss
                     where s.ViewTemplate != null
                     select s.ViewTemplate;

            var template = ts.FirstOrDefault();

            var model = PrepareSlideshowModel(ss);

            return template != null ? PartialView(template, model) : PartialView(model);
        }


        [ChildActionOnly]
        public ActionResult PromotionDisplay()
        {
            return PartialView();
        }

        [ChildActionOnly]
		[OutputCache(VaryByParam = "*", Duration = 600)]
        public ActionResult Slideshow(int type, string contentCategory = null, int contentId = 0)
        {
            PictureDisplayType t = (PictureDisplayType)type;
            t |= PictureDisplayType.Slideshow;

            IList<Slideshow> ss = _pictureDisplayService.GetSlideshowsByTypeAndContentCategory(t, contentCategory, contentId, true);

            var ts = from s in ss
                     where s.ViewTemplate != null
                     select s.ViewTemplate;

            var template = ts.FirstOrDefault();

            var model = PrepareSlideshowModel(ss);

            if (template != null)
            {
                return PartialView(template, model);
            }

            return PartialView(model);
        }
        
        [NonAction]
        protected IList<SlideshowModel> PrepareSlideshowModel(IList<Slideshow> slideshows)
        {
            var model = new List<SlideshowModel>();

            if (slideshows == null) return model;

            foreach (var slideshow in slideshows)
            {
                var m = new SlideshowModel();

                if (slideshow == null) continue;

                m.Type = slideshow.Type;
                m.Height = slideshow.Height;
                m.Width = slideshow.Width;

                switch (slideshow.Type)
                {
                    case SlideshowType.Carousel:
                        m.AutoSlideInterval = slideshow.AutoSlideInterval ?? _slideshowGlobalSettings.AutoSlideInterval;
                        m.HoverPause = slideshow.Navigation ?? _slideshowGlobalSettings.HoverPause;
                        m.Links = slideshow.Links ?? _slideshowGlobalSettings.Links;
                        m.Navigation = slideshow.Navigation ?? _slideshowGlobalSettings.Navigation;
                        m.ShowTitle = slideshow.ShowTitle ?? _slideshowGlobalSettings.ShowTitle;
                        break;
                    case SlideshowType.ThreeD:
                        m.AutoRotate = slideshow.AutoRotate ?? _slideshowGlobalSettings.AutoRotate;
                        m.MouseWheel = slideshow.MouseWheel ?? _slideshowGlobalSettings.MouseWheel;
                        m.Speed = slideshow.Speed ?? _slideshowGlobalSettings.Speed;
                        m.XPosition = slideshow.XPosition ?? _slideshowGlobalSettings.XPosition;
                        m.YPosition = slideshow.YPosition ?? _slideshowGlobalSettings.YPosition;
                        m.YRadius = slideshow.YRadius ?? _slideshowGlobalSettings.YRadius;
                        break;
                    default:
                        continue;
                }

                m.PictureLinks = PreparePictureLinks(slideshow.PictureLinkCollection);
                model.Add(m);
            }

            return model;
        }

        [NonAction]
        protected PictureLinkCollectionModel PreparePictureLinkCollectionModel(PictureLinkCollection pictureLinks)
        {
            var model = new PictureLinkCollectionModel();

            if (pictureLinks == null)
            {
                model.PictureLinks = new List<PictureLinkModel>();
            }
            return model;
        }

        [NonAction]
        protected IList<PictureLinkModel> PreparePictureLinks(PictureLinkCollection pictureLinks)
        {
            var model = new List<PictureLinkModel>();

            var profiler = MiniProfiler.Current;

            using (profiler.Step("Call GetPictureUrl " + pictureLinks.PictureLinks.Count))
            {
                foreach (PictureLink pl in pictureLinks.PictureLinks.Where(d=>d.Visible).OrderBy(pl => pl.DisplayOrder))
                {
                    var pictureLinkCacheKey = string.Format(ModelCacheEventConsumer.PICTURE_LINK_MODEL_KEY, pl.Id, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured());

                    model.Add(_cacheManager.Get(pictureLinkCacheKey, () =>
                    {
                        var pm = new PictureLinkModel();
                        {
                            pm.AlternateText = pl.GetLocalized(p => p.Alt);
                            pm.Title = pl.GetLocalized(p => p.DisplayText);
                            pm.Url = pl.GetLocalized(p => p.Url);
                            pm.FullSizeImageUrl = this._pictureService.GetPictureUrl(pl.PictureId);
                        };
                        return pm;
                    }));
                }
            }
            return model;
        }
    }
}
